﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Reflection;
using System.Runtime.InteropServices;
using System.IO;

namespace ThumbcacheHelper
{
    public enum FileId
    {
        Thumbs32,
        Thumbs96,
        Thumbs256,
        Thumbs1024,
        ThumbsIdx,
        ThumbsSR,
        WinEdb,
        Unknown
    }

    public partial class FrmMain : Form
    {
        List<EntryData> entries = new List<EntryData>();
        CacheCruncher cacheCruncher = null;

        public FrmMain()
        {
            InitializeComponent();
            log(String.Format("Version {0} started at {1}.", Assembly.GetExecutingAssembly().GetName().Version, DateTime.Now.ToString()));
            log(String.Format("Working folder: {0}", Application.StartupPath), BlankLine: true);
        }

        private void New_Click(object sender, EventArgs e)
        {
            FrmInput input = new FrmInput();
            if (input.ShowDialog() == DialogResult.OK)
            {
                enableGUI(false);
                entries.Clear();

                cacheCruncher = new CacheCruncher(this, input.InputFiles);
                cacheCruncher.Start();
            }
        }

        public void ResetProgressBar()
        {
            tsProgress.Value = 0;
        }

        public void SetProgressMax(int max)
        {
            tsProgress.Maximum = max;
        }

        public void SetStatus(string msg)
        {
            tsStatus.Text = msg;            
        }

        public void IncrementProgressBar(int Value)
        {
            tsProgress.Value += Value;
        }

        public void AddEntry(EntryData entryData)
        {
            entries.Add(entryData);            
            tsProgress.Value++;
        }

        public bool SetIdxOffset(FileId FileId, string Hash, long Offset, long IdxOffset)
        {
            for(int i=0; i<entries.Count;i++)
            {
                EntryData ed = entries[i];
                if (ed.FileId == FileId && ed.EntryHash == Hash && ed.Offset == Offset)
                {
                    ed.IdxOffset = IdxOffset;                    
                    return true;
                }
            }

            return false;
        }

        public void UpdateDataGridView()
        {
            SetStatus(String.Empty);
            folvOutput.SetObjects(entries);
            enableGUI(true);
        }

        public EntryData GetEntryByHash(long Hash, FileId FileId)
        {
            byte[] b = BitConverter.GetBytes(Hash);
            Array.Reverse(b);
            string hashAsString = Utils.ByteArrayToByteString(b).ToLower();

            foreach (EntryData ed in entries)
            {
                if (ed.EntryHash == hashAsString && ed.FileId == FileId)
                    return ed;
            }

            return null;
        }        

        void enableGUI(bool enable)
        {
            tsbtnNew.Enabled = enable;
            tsbtnCancel.Enabled = !enable;
        }

        /// <summary>
        /// Add a string to the log
        /// </summary>
        /// <param name="Message">The string to add</param>
        /// <param name="BlankLine">Inlcude a blank line after the string</param>
        public void log(String Message, Color? colour = null, bool BlankLine = false)
        {
            int start = rtbLog.TextLength;
            rtbLog.AppendText(String.Format("{0}{1}{2}", Message, Environment.NewLine, BlankLine ? Environment.NewLine : String.Empty));
            int end = rtbLog.TextLength;

            if (colour != null)
            {
                rtbLog.Select(start, end - start);
                {
                    rtbLog.SelectionColor = colour.Value;
                }
                rtbLog.SelectionLength = 0;
            }            
        }

        /// <summary>
        /// Update the picture box when the selected thumbcache entry changes
        /// </summary>        
        private void folvOutput_SelectedIndexChanged(object sender, EventArgs e)
        {
            object o = folvOutput.SelectedObject;
            if (o != null)
            {
                EntryData item = (EntryData)o;
                if (item.DataSize > 0)
                {
                    MemoryStream ms = new MemoryStream(item.getThumbBytes());
                    pbThumb.Image = Image.FromStream(ms);
                }
                else
                {
                    pbThumb.Image = null;
                }
            }
        }

        private void tsbtnCancel_Click(object sender, EventArgs e)
        {
            tsbtnCancel.Enabled = false;
            log("Cancel request received. Please wait.", Color.IndianRed);
            cacheCruncher.Cancel();
        }

        private void FrmMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (cacheCruncher != null && cacheCruncher.IsRunning())
                e.Cancel = true;
        }
    }
}
